package com.innovation.ic.im.end.base.service.im_erp9.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.innovation.ic.b1b.framework.manager.RedisManager;
import com.innovation.ic.im.end.base.mapper.im_erp9.AccountMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.GroupMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.RefGroupAccountMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.RefGroupAccountOperationMapper;
import com.innovation.ic.im.end.base.model.im_erp9.Account;
import com.innovation.ic.im.end.base.model.im_erp9.Group;
import com.innovation.ic.im.end.base.model.im_erp9.RefGroupAccount;
import com.innovation.ic.im.end.base.model.im_erp9.RefGroupAccountOperation;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.Constants;
import com.innovation.ic.im.end.base.pojo.constant.RedisStorage;
import com.innovation.ic.im.end.base.pojo.constant.ToppingType;
import com.innovation.ic.im.end.base.pojo.im_erp9.GroupPojo;
import com.innovation.ic.im.end.base.service.im_erp9.RefGroupAccountService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * RefGroupAccount的具体实现类
 */
@Service
@Transactional
public class RefGroupAccountServiceImpl extends ServiceImpl<RefGroupAccountMapper, RefGroupAccount> implements RefGroupAccountService {
    private static final Logger log = LoggerFactory.getLogger(RefGroupAccountServiceImpl.class);

    @Resource
    private RefGroupAccountMapper refGroupAccountMapper;

    @Resource
    private RefGroupAccountOperationMapper refGroupAccountOperationMapper;

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private RedisManager redisManager;

    @Resource
    private AccountMapper accountMapper;

    /**
     * 删除ref_group_account表中的所有数据
     *
     * @return
     */
    @Override
    public ServiceResult<Boolean> truncateTable() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        refGroupAccountMapper.truncateTable();

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 插入RefGroupAccount对象
     *
     * @param refGroupAccount
     * @return
     */
    @Override
    public ServiceResult<Boolean> saveRefGroupAccount(RefGroupAccount refGroupAccount) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        int refGroupAccountDataCount = getRefGroupAccountDataCount(refGroupAccount);
        if(refGroupAccountDataCount == 0){
            baseMapper.insert(refGroupAccount);
        }else{
            log.info("账号和群组的关系表中,群组id:[{}],账号id:[{}],账号:[{}]数据已存在,跳过当前数据处理", refGroupAccount.getGroupId(), refGroupAccount.getAccountId(), refGroupAccount.getUsername());
        }

        serviceResult.setMessage(ServiceResult.INSERT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 根据groupId，查找username不在usernameList范围内的用户
     *
     * @param groupId
     * @param usernameList
     * @return
     */
    @Override
    public ServiceResult<List<RefGroupAccount>> findByGroupIdAndNotInList(String groupId, List<String> usernameList) {
        ServiceResult<List<RefGroupAccount>> serviceResult = new ServiceResult<List<RefGroupAccount>>();

        QueryWrapper<RefGroupAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id", groupId);
        if (null != usernameList && usernameList.size() > 0) {
            queryWrapper.notIn("username", usernameList);
        }
        List<RefGroupAccount> refGroupAccountList = baseMapper.selectList(queryWrapper);

        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(refGroupAccountList);
        return serviceResult;
    }

    /**
     * 根据groupId，修改对应记录的last_contact_time字段
     * @param groupId
     * @return
     */
    @Override
    public ServiceResult<Boolean> updateLastContactTimeByGroupId(String groupId) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        refGroupAccountOperationMapper.updateLastContactTimeByGroupId(groupId);

        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 根据群组id，账号id,账号,状态,去置顶
     * @param groupId
     * @param accountId
     * @param username
     * @param status
     * @return
     */
    @Override
    public ServiceResult<Boolean> updateRefGroupAccount(String groupId, String accountId, String username, Integer status) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        Boolean result = Boolean.FALSE;
        String message;

        try {
            // 根据默认群组id、账号id查询账号和群组的操作表数据
            RefGroupAccountOperation refGroupAccountOperation = refGroupAccountOperationMapper.selectDataByGroupAccountUsername(groupId, accountId, username);
            if(refGroupAccountOperation == null){
                log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]查询账号和群组的操作表数据为空,数据不存在,插入新数据", groupId, accountId, username);
                refGroupAccountOperation = new RefGroupAccountOperation();
                refGroupAccountOperation.setGroupId(groupId);
                refGroupAccountOperation.setAccountId(accountId);
                refGroupAccountOperation.setUsername(username);
                if (status.equals(ToppingType.YES)) {
                    refGroupAccountOperation.setToppingTime(new Date(System.currentTimeMillis()));
                }
                int insert = refGroupAccountOperationMapper.insert(refGroupAccountOperation);
                if(insert > 0){
                    log.info("插入数据成功");
                    result = Boolean.TRUE;
                }
            }else{
                // 查询到数据,进行更新操作
                if (status.equals(ToppingType.YES)) {
                    refGroupAccountOperation.setToppingTime(new Date(System.currentTimeMillis()));
                    int i = refGroupAccountOperationMapper.updateById(refGroupAccountOperation);
                    if(i > 0){
                        log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]获取数据置顶成功", groupId, accountId, username);
                        result = Boolean.TRUE;
                    }
                } else {
                    // 取消置顶
                    refGroupAccountOperation.setToppingTime(null);
                    int i = refGroupAccountOperationMapper.setToppingTimeNull(refGroupAccountOperation);
                    if(i > 0){
                        log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]获取数据取消置顶成功", groupId, accountId, username);
                        result = Boolean.TRUE;
                    }
                }
            }
            message = ServiceResult.UPDATE_SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            log.error("根据群组id，账号id,账号,状态,去置顶方法执行出现问题,原因:",e);
            message = ServiceResult.UPDATE_FAIL + ",原因:" + e.getMessage();
        }

        serviceResult.setMessage(message);
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 通过accountId 去ref_group_account表获取对应的 id
     *
     * @param id
     * @return
     */
    @Override
    public ServiceResult<List<RefGroupAccount>> findByRealId(String id) {
        ServiceResult<List<RefGroupAccount>> serviceResult = new ServiceResult<List<RefGroupAccount>>();
        List<RefGroupAccount> refGroupAccountList = refGroupAccountMapper.findByRealId(id);

        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(refGroupAccountList);
        return serviceResult;
    }

    /**
     * 根据groupId,accountId,username去修改status状态
     *
     * @param groupId
     * @param accountId
     * @param username
     * @param status
     * @return
     */
    @Override
    public ServiceResult<Boolean> updateRefGroupAccountStatus(String groupId, String accountId, String username, Integer status) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        Boolean result = Boolean.FALSE;
        String message;

        try {
            // 根据默认群组id、账号id查询账号和群组的操作表数据
            RefGroupAccountOperation refGroupAccountOperation = refGroupAccountOperationMapper.selectDataByGroupAccountUsername(groupId, accountId, username);
            if(refGroupAccountOperation == null){
                log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]查询账号和群组的操作表数据为空,数据不存在,插入新数据", groupId, accountId, username);
                refGroupAccountOperation = new RefGroupAccountOperation();
                refGroupAccountOperation.setGroupId(groupId);
                refGroupAccountOperation.setAccountId(accountId);
                refGroupAccountOperation.setUsername(username);
                refGroupAccountOperation.setNoReminder(status);
                int insert = refGroupAccountOperationMapper.insert(refGroupAccountOperation);
                if(insert > 0){
                    log.info("插入数据成功");
                    result = Boolean.TRUE;
                }
            }else{
                refGroupAccountOperation.setNoReminder(status);
                int i = refGroupAccountOperationMapper.updateById(refGroupAccountOperation);
                if(i > 0){
                    log.info("更新数据成功");
                    result = Boolean.TRUE;
                }
            }
            message = ServiceResult.UPDATE_SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            log.error("根据groupId,accountId,username去修改status状态方法执行出现问题,原因:",e);
            message = ServiceResult.UPDATE_FAIL + ",原因:" + e.getMessage();
        }

        serviceResult.setMessage(message);
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 根据要插入数据库的数据实体查询库中与当前数据一致的结果数量
     * @param refGroupAccount 群组和账号的关系表实体
     * @return 查询结果
     */
    private int getRefGroupAccountDataCount(RefGroupAccount refGroupAccount) {
        QueryWrapper<RefGroupAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("group_id", refGroupAccount.getGroupId());
        queryWrapper.eq("account_id", refGroupAccount.getAccountId());
        queryWrapper.eq("username", refGroupAccount.getUsername());
        return refGroupAccountMapper.selectCount(queryWrapper);
    }

    /**
     * 根据条件查询自定义群组信息
     * @param map 查询条件
     * @return 返回自定义群组信息
     */
    @Override
    public ServiceResult<GroupPojo> getGroupDetailInfoByParam(Map<String, Object> map) {
        ServiceResult<GroupPojo> serviceResult = new ServiceResult<GroupPojo>();

        log.info("根据查询条件:[{}]查询默认群组信息", new JSONObject(map).toJSONString());
        GroupPojo groupPojo = refGroupAccountMapper.getGroupDetailInfoByParam(map);
        if(groupPojo != null){
            // 根据查询条件查询账号信息集合
            log.info("根据查询条件:[{}]查询账号信息集合", new JSONObject(map).toJSONString());
            List<Account> accounts = accountMapper.selectAccountByGroupParam(map);
            if(accounts != null && accounts.size() > 0){
                groupPojo.setAccountList(accounts);
            }else{
                log.info("查询自定义群组成员列表为空");
                groupPojo.setAccountList(new ArrayList<>());
            }
        }else{
            log.info("查询默认群组信息为空,不进行默认群组成员列表查询操作");
        }

        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(groupPojo);
        return serviceResult;
    }

    /**
     * 根据用户设置默认群组聊天内容不可见时间
     * @param map 更新条件
     * @return 返回更新结果
     */
    @Override
    public ServiceResult<Boolean> invisibleChatRecordSet(Map<String, Object> map) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        Boolean result = Boolean.FALSE;
        String message;

        log.info("根据用户设置默认群组聊天内容不可见时间,更新条件:[{}]", new JSONObject(map).toJSONString());
        try {
            String groupId = (String) map.get(Constants.GROUP_ID);
            String accountId = (String) map.get(Constants.ACCOUNT_ID);
            String username = (String) map.get(Constants.USER_NAME);

            // 根据默认群组id、账号id查询账号和群组的操作表数据
            RefGroupAccountOperation refGroupAccountOperation = refGroupAccountOperationMapper.selectDataByGroupAccountUsername(groupId, accountId, username);
            if(refGroupAccountOperation == null){
                log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]查询账号和群组的操作表数据为空,数据不存在,插入新数据", groupId, accountId, username);
                int insert = insertRefGroupAccountOperation(groupId, accountId, username);
                if(insert > 0){
                    log.info("插入数据成功");
                    result = Boolean.TRUE;
                }
            }else{
                refGroupAccountOperation.setContentInvisibleTime(new Date(System.currentTimeMillis()));
                int i = refGroupAccountOperationMapper.updateById(refGroupAccountOperation);
                if(i > 0){
                    log.info("更新数据成功");
                    result = Boolean.TRUE;
                }
            }
            message = ServiceResult.UPDATE_SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            log.error("根据用户设置默认群组聊天内容不可见时间方法执行出现问题,原因:",e);
            message = ServiceResult.UPDATE_FAIL + ",原因:" + e.getMessage();
        }

        serviceResult.setMessage(message);
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 删除最近联系群组并清除聊天记录
     * @param map 条件
     * @return 返回删除结果
     */
    @Override
    public ServiceResult<Boolean> deleteGroupChat(Map<String, Object> map) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        Boolean result = Boolean.FALSE;
        String message = ServiceResult.UPDATE_FAIL;

        String groupId = (String) map.get(Constants.GROUP_ID);
        String accountId = (String) map.get(Constants.ACCOUNT_ID);
        String username = (String) map.get(Constants.USER_NAME);

        // 清除当前用户对群组groupId的最近联系时间
        RefGroupAccountOperation refGroupAccountOperation = refGroupAccountOperationMapper.selectDataByGroupAccountUsername(groupId, accountId, username);
        if(refGroupAccountOperation == null){
            log.info("根据默认群组id:[{}]、账号id:[{}]、用户名:[{}]查询账号和群组的操作表数据为空,数据不存在,插入新数据", groupId, accountId, username);
            int insert = insertRefGroupAccountOperation(groupId, accountId, username);
            if(insert > 0){
                log.info("插入数据成功");
                result = Boolean.TRUE;
                message = ServiceResult.UPDATE_SUCCESS;
            }
        }else{
            int i = refGroupAccountOperationMapper.deleteGroupChat(map);
            if(i > 0){
                log.info("更新数据成功");
                result = Boolean.TRUE;
                message = ServiceResult.UPDATE_SUCCESS;
            }
        }

        serviceResult.setMessage(message);
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 根据Group表,将ref_group_account表的数据统计数量导入redis
     * @return
     */
    @Override
    public ServiceResult<Boolean> importRefGroupAccountIntoRedis() {
        ServiceResult<Boolean> returnResult = new ServiceResult<>();
        //获取默认分组
        QueryWrapper<Group> queryWrapper = new QueryWrapper<Group>();
        List<Group> groupList= groupMapper.selectList(queryWrapper);
        if (groupList != null && groupList.size() > 0) {
            for (Group group : groupList) {
                // 查询默认群组人数
                QueryWrapper<RefGroupAccount> refGroupAccountQueryWrapper = new QueryWrapper<>();
                queryWrapper.eq(Constants.GROUP_ID_FIELD, group.getId());
                Integer count = refGroupAccountMapper.selectCount(refGroupAccountQueryWrapper);
                redisManager.set(RedisStorage.REF_GROUP_ACCOUNT_BY_GROUP_ID_COUNT_PREFIX + group.getId(),JSON.toJSONString(count));
            }
        }
        returnResult.setMessage(ServiceResult.SYNC_SUCCESS);
        returnResult.setSuccess(Boolean.TRUE);
        returnResult.setResult(Boolean.TRUE);
        return returnResult;
    }

    /**
     * 根据默认群组id获取群组人数
     * @param groupId 默认群组id
     * @return 返回群组人数
     */
    @Override
    public ServiceResult<Integer> getCountByGroupId(String groupId) {
        ServiceResult<Integer> serviceResult = new ServiceResult<>();

        // 查询默认群组人数
        QueryWrapper<RefGroupAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Constants.GROUP_ID_FIELD, groupId);
        Integer count = refGroupAccountMapper.selectCount(queryWrapper);

        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(count);
        return serviceResult;
    }

    /**
     * 查询当前默认群组中除自己之外的用户账号列表
     * @param groupId 默认群组id
     * @param userAccount 发送消息的用户账号
     * @return 返回除自己之外的用户账号列表
     */
    @Override
    public ServiceResult<List<String>> getGroupAccountsNotHaveSelf(String groupId, String userAccount) {
        ServiceResult<List<String>> serviceResult = new ServiceResult<>();
        // 查询当前默认群组中除自己之外的用户账号列表
        List<String> list = refGroupAccountMapper.getGroupAccountsNotHaveSelf(groupId, userAccount);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(list);
        return serviceResult;
    }

    /**
     * 查询当前默认群组中的用户账号
     * @param groupId 默认群组id
     * @return 返回默认群组中的用户账号列表
     */
    @Override
    public ServiceResult<List<String>> getGroupAccounts(String groupId) {
        ServiceResult<List<String>> serviceResult = new ServiceResult<>();
        // 查询当前默认群组中的用户账号
        List<String> list = refGroupAccountMapper.getGroupAccounts(groupId);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(list);
        return serviceResult;
    }

    /**
     * 更新用户username组groupId的最近联系时间
     * @param groupId  默认群组id
     * @param accountId  用户账号
     * @param username 用户名
     * @return 返回更新结果
     */
    @Override
    public ServiceResult<Boolean> updateLastContactTime(String groupId, String accountId, String username) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        Boolean result = Boolean.FALSE;
        String message = ServiceResult.UPDATE_FAIL;

        RefGroupAccountOperation historyData = null;

        QueryWrapper<RefGroupAccountOperation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Constants.GROUP_ID_FIELD, groupId);
        queryWrapper.eq(Constants.ACCOUNT_ID_FIELD, accountId);
        queryWrapper.eq(Constants.USER_NAME, username);
        queryWrapper.orderByDesc(Constants.LAST_CONTACT_TIME_FIELD);
        List<RefGroupAccountOperation> refGroupAccountOperations = refGroupAccountOperationMapper.selectList(queryWrapper);
        if(refGroupAccountOperations != null && refGroupAccountOperations.size() > 0){
            historyData = refGroupAccountOperations.get(0);
        }
        if(historyData == null){
            // 没有这条数据，需要插入新数据
            RefGroupAccountOperation refGroupAccountOperation = new RefGroupAccountOperation();
            refGroupAccountOperation.setLastContactTime(new Date(System.currentTimeMillis()));
            refGroupAccountOperation.setGroupId(groupId);
            refGroupAccountOperation.setAccountId(accountId);
            refGroupAccountOperation.setUsername(username);
            int insert = refGroupAccountOperationMapper.insert(refGroupAccountOperation);
            if(insert > 0){
                result = Boolean.TRUE;
                message = ServiceResult.UPDATE_SUCCESS;
                log.info("用户:[{}]组:[{}]的操作表数据不存在,插入数据及最近联系时间成功", username, groupId);
            }
        }else{
            if(historyData.getLastContactTime() == null){
                // 更新用户在群组的最近联系时间
                int update = refGroupAccountOperationMapper.updateLastContactTime(groupId, accountId, username);
                if(update > 0){
                    result = Boolean.TRUE;
                    message = ServiceResult.UPDATE_SUCCESS;
                    log.info("更新用户:[{}]组:[{}]的最近联系时间成功", username, groupId);
                }
            }else{
                result = Boolean.TRUE;
                message = ServiceResult.UPDATE_SUCCESS;
                log.info("用户:[{}]组:[{}]的最近联系时间已存在,不进行更新操作", username, groupId);
            }
        }

        serviceResult.setMessage(message);
        serviceResult.setSuccess(result);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 插入账号和群组的操作表数据
     * @param groupId 默认群组id
     * @param accountId 账号id
     * @param username 用户名
     * @return 返回插入结果
     */
    private int insertRefGroupAccountOperation(String groupId, String accountId, String username){
        RefGroupAccountOperation refGroupAccountOperation = new RefGroupAccountOperation();
        refGroupAccountOperation.setGroupId(groupId);
        refGroupAccountOperation.setAccountId(accountId);
        refGroupAccountOperation.setUsername(username);
        refGroupAccountOperation.setContentInvisibleTime(new Date(System.currentTimeMillis()));
        return refGroupAccountOperationMapper.insert(refGroupAccountOperation);
    }
}